package com.seleniti.enpareja.controller.ui.view;

import java.util.Date;
import java.util.List;
import java.util.Set;

import org.ioc.commons.domain.features.HasBoards;
import org.ioc.commons.domain.features.IsBoard;
import org.ioc.commons.flowcontrol.actioncontroller.IsExternalAction;
import org.ioc.commons.flowcontrol.eventbus.IsEvent;
import org.ioc.commons.flowcontrol.operationmanager.IsOperation;
import org.ioc.commons.ui.HasEnabled;
import org.ioc.commons.ui.HasLoader;
import org.ioc.commons.ui.HasText;
import org.ioc.commons.ui.HasValue;
import org.ioc.commons.ui.IsView;
import org.ioc.commons.ui.IsViewPresenter;

import com.seleniti.enpareja.controller.common.domain.LoggedUserInfo;
import com.seleniti.enpareja.controller.model.integration.database.domain.Food;
import com.seleniti.enpareja.controller.ui.view.MealsView.Board;

public interface MealsView extends EnParejaView<MealsView.Event, MealsView.Operation, MealsView.Action>, HasLoader,
		HasEnabled, HasBoards<Board> {

	@interface Fires {
		MealsView.Event[] value();
	}

	@interface Invokes {
		MealsView.Action[] value();
	}

	@interface Performs {
		MealsView.Operation[] value();
	}

	public enum Event implements IsEvent {
	}

	public enum Operation implements IsOperation {
		GettingData, Saving, Deleting
	}

	public enum Action implements IsExternalAction {
	}

	public interface Presenter extends IsViewPresenter {

		void onActionModeChanged();

		void onMealModified();

		void onDateFilterChanged();

		void onSingleSelectionChanged();

		void onDoubleSelectionChanged();

		boolean onGoBoardBack();

		void onRefreshData();
	}

	public enum ActionMode {
		DELETE_ELEMENT, MODIFY_ELEMENT, SWITCH_MEALS;
	}

	public static class DoubleSelection {
		private Food element;
		private boolean dinner;

		public Food getElement() {
			return element;
		}

		public void setElement(Food element) {
			this.element = element;
		}

		public boolean isDinner() {
			return dinner;
		}

		public void setDinner(boolean dinner) {
			this.dinner = dinner;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + (dinner ? 1231 : 1237);
			result = prime * result + ((element == null || element.getFoodId() == null) ? 0 : element.getFoodId().hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			DoubleSelection other = (DoubleSelection) obj;
			if (dinner != other.dinner)
				return false;
			if (element == null) {
				if (other.element != null)
					return false;
			} else if (!element.equals(other.element))
				return false;
			return true;
		}
	}

	public enum Board implements IsBoard {
		MAIN_LIST, EDIT_FORM
	}

	void setActionMode(ActionMode mode);

	List<Food> foodsList();

	ActionMode getActionMode();

	Set<Food> getSingleSelection();

	void showModifyForm(Food toModify);

	void saveModificationForm();

	void hideModificationForm();

	HasValue<Date> date();

	HasValue<Date> filterToDate();

	HasValue<Date> filterFromDate();

	HasText dinner();

	HasText lunch();

	Set<DoubleSelection> getDoubleSelection();

	HasValue<LoggedUserInfo> loggedUserInfo();

}
